/*
 * Copyright 2019 成都深地领航能源科技有限公司. All rights reserved.
 * PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.sdlh.demo.concurrent;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author 成都深地领航能源科技有限公司
 */
@Slf4j
public class CompletableFutureDemo {
    public static void main(String[] args) {
        ThreadPoolExecutor pool1 = new ThreadPoolExecutor(4, 5, 10,
                                            TimeUnit.SECONDS,
                                            new ArrayBlockingQueue<>(50),
                                            Thread.ofPlatform().name("平台非守护线程池-", 1).factory());
        ThreadPoolExecutor pool2 = new ThreadPoolExecutor(4, 5, 10,
                                            TimeUnit.SECONDS,
                                            new ArrayBlockingQueue<>(50),
                                            Thread.ofVirtual().name("虚拟非守护线程池-", 1).factory());

        try {
            test(pool1);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        log.info("主线程退出");
    }

    private static void test(ThreadPoolExecutor pool) throws InterruptedException {
        List<CompletableFuture> futureList = new ArrayList<>();

        futureList.add(CompletableFuture.runAsync(() -> {
            run(1000);
            log.info("线程1结束");
        }, pool));
        futureList.add(CompletableFuture.runAsync(() -> {
            run(1500);
            log.info("线程2结束");
        }, pool));
        futureList.add(CompletableFuture.runAsync(() -> {
            run(800);
            log.info("线程3结束");
        }, pool));
        futureList.add(CompletableFuture.runAsync(() -> {
            run(500);
            log.info("线程4结束");
        }, pool));

        CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()])).join();
        log.info("所有线程全部执行完毕");
        pool.shutdownNow();
    }

    private static void run(long time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            log.error(e.getMessage(), e);
        }
    }
}
